#pragma once
#include <boost/asio.hpp>
#include <future>
#include <utility>
#include <memory>
#include <optional>

namespace gateway::beast_http {

// 将阻塞任务投递到 boost::asio::thread_pool，并返回 future（简单版）
template <typename F>
auto post_to_pool(boost::asio::thread_pool& pool, F&& f) {
    using R = decltype(f());
    auto task = std::make_shared<std::packaged_task<R()>>(std::forward<F>(f));
    std::future<R> fut = task->get_future();
    boost::asio::post(pool, [task]() { (*task)(); });
    return fut;
}

// 完整协程桥接：在工作线程池执行 f()，完成后通过取消一个超时很久的计时器来唤醒当前协程
// 优点：实现简单、依赖稳定 API；缺点：需要一个计时器对象
template <typename R, typename F>
auto co_offload(boost::asio::io_context& ioc, boost::asio::thread_pool& pool, F&& f)
    -> boost::asio::awaitable<R>
{
    namespace net = boost::asio;
    using timer_t = net::steady_timer;

    auto exec = co_await net::this_coro::executor;
    auto result = std::make_shared<std::optional<R>>();
    auto err = std::make_shared<std::exception_ptr>();
    auto timer = std::make_shared<timer_t>(ioc);

    // 设一个超长超时，等待工作线程回投来取消
    timer->expires_after(std::chrono::hours(24));

    net::post(pool, [exec, timer, result, err, fn = std::forward<F>(f)]() mutable {
        try {
            *result = fn();
        } catch (...) {
            *err = std::current_exception();
        }
        // 回投到 io_context，取消计时器，唤醒协程
        net::post(exec, [timer]() mutable {
            boost::system::error_code ec;
            timer->cancel(ec);
        });
    });

    boost::system::error_code ec;
    co_await timer->async_wait(net::redirect_error(net::use_awaitable, ec));
    if (*err) std::rethrow_exception(*err);
    co_return std::move(**result);
}

} // namespace gateway::beast_http
